home *** CD-ROM | disk | FTP | other *** search
- /*
- * This is the view from which NextMatrix and TetMatrix inherit.
- *
- * The major data structures are.
- * id *iconMatrix; Holds the id of the block that is in the current
- * (row, column).
- */
- #import <appkit/NXImage.h>
- #import <appkit/nextstd.h>
- #import <dpsclient/psops.h>
- #import "Minimatrix.h"
-
- @implementation Minimatrix
-
- - initFrame:(const NXRect *)frameRect
- {
- return [self initFrame:frameRect bitmap:nil numRows:0 numCols:0];
- }
-
- - initFrame:(const NXRect *)frameRect
- numRows:(int)rowsHigh numCols:(int)colsWide
- {
- return [self initFrame:frameRect
- bitmap:nil
- numRows:rowsHigh numCols:colsWide];
- }
-
- - initFrame:(const NXRect *)frameRect
- bitmap:theBitmap numRows
- :(int)rowsHigh numCols
- :(int)colsWide
- {
- [super initFrame:frameRect];
-
- numRows = rowsHigh;
- numCols = colsWide;
- NX_MALLOC(iconMatrix, id, numRows * numCols);
- backgroundGray = NX_LTGRAY;
- inset.width = inset.height = 0.0;
- insetBounds = bounds;
- intercell = elementSize = inset;
-
- [self setBitmap:theBitmap];
- return self;
- }
-
- /*
- * Return the id of the bitmap at (row,column) if one exists, else nil.
- */
- - bitmapAt:(int)row :(int)column
- {
- return (row < 0 || column < 0 || row >= numRows || column >= numCols) ?
- nil : *(iconMatrix + row * numCols + column);
- }
-
- - displayAt:(int)row :(int)column
- {
- NXRect destRect;
-
- NXSetRect(&destRect,
- inset.width + column * (intercell.width + elementSize.width),
- inset.height + row * (intercell.width + elementSize.width),
- elementSize.width + intercell.width,
- elementSize.height + intercell.height);
-
- return [self display:&destRect :1];
- }
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
- int rowc, colc;
- int rectc;
- NXRect destRect;
- id *iconMatrixPiece;
- const NXRect *rectp;
- static int bsides[] = {NX_YMIN, NX_XMAX, NX_YMAX, NX_XMIN,
- NX_YMIN, NX_XMAX, NX_YMAX, NX_XMIN};
-
- static float bgrays[] = {NX_WHITE, NX_WHITE, NX_DKGRAY, NX_DKGRAY,
- NX_LTGRAY, NX_WHITE, NX_DKGRAY, NX_DKGRAY};
-
- PSsetgray(backgroundGray);
- NXRectFillList(rects, rectCount); // Clear old areas
-
- destRect = bounds;
-
- // Draw the insetRect around the border of the game when a Piece
- // intersects with the border.
-
- if ((inset.width || inset.height) && !NXContainsRect(&insetBounds, rects)) {
- NXDrawTiledRects(&destRect, (NXRect *)0, bsides, bgrays, 8);
- }
-
- NXSetRect(&destRect, inset.width + intercell.width,
- inset.height + intercell.height,
- elementSize.width, elementSize.height);
-
- iconMatrixPiece = iconMatrix;
-
- // Redraw all of the Pieces that have changed
- for (rowc = 0; rowc < numRows; rowc++) {
- for (colc = 0; colc < numCols; colc++) {
- if (*iconMatrixPiece) {
- rectc = rectCount;
- rectp = rects;
- while (rectc--) {
- if (NXIntersectsRect(&destRect, rectp++)) {
- // If we assume the piece contains no alpha then we could use
- // NX_COPY
- [*iconMatrixPiece composite:NX_SOVER toPoint:&destRect.origin];
- break;
- }
- }
- }
- // Add block's width + space b/w each block to get new X coord
- destRect.origin.x += elementSize.width + intercell.width;
- iconMatrixPiece++; // Do next column in iconMatrix
- }
- destRect.origin.x = inset.width + intercell.width;
-
- // Add the block's height + intercell.height
- destRect.origin.y += elementSize.height + intercell.height;
- }
- return self;
- }
-
- /*
- * Private method.
- */
- - getIntercell:(NXSize *)aSize
- {
- *aSize = intercell;
- return self;
- }
-
- - getRect:(NXRect *)theRect for:(int)row :(int)column
- {
- theRect->size = elementSize; // Get block's image size
- return [self point:&theRect->origin for:row :column];
- }
-
- /*
- * Calculate the TetrisView coordinate given the Tetrix (row,column)
- */
- - point:(NXPoint *)thePoint for:(int)row :(int)column
- {
- thePoint->x = inset.width + (column + 1) * intercell.width +
- column * elementSize.width;
- thePoint->y = inset.height + (row + 1) * intercell.height +
- row * elementSize.height;
- return self;
- }
-
-
- - setBackgroundGray:(float)gray
- {
- backgroundGray = gray;
- return self;
- }
-
- - setBitmap:theBitmap
- {
- id *iconMatrixPiece;
-
- #ifdef DEBUG
- printf("setBitmap\n");
- #endif
-
- iconMatrixPiece = iconMatrix + numRows * numCols;
- while (iconMatrixPiece > iconMatrix)
- *--iconMatrixPiece = theBitmap;
-
- if (theBitmap)
- [theBitmap getSize:&elementSize];
- return self;
- }
- /*
- * Set the current (row, column) of the iconMatrix equal to the id of
- * the block that was just dropped.
- *
- * There is a bug in this program. Occasionally, an invalid row
- * is generated.
- *
- * theBitmap row, col = (24, 6)
- * theBitmap row, col = (23, 6)
- * theBitmap row, col = (23, 7)
- * theBitmap row, col = (25, 3)
- * theBitmap row, col = (698590, 3)
- */
- - setBitmap:theBitmap at:(int)row :(int)column
- {
- if (row < numRows && row >= 0 && column < numCols && column >= 0) {
- *(iconMatrix + row * numCols + column) = theBitmap;
- } else {
- fprintf(stderr, "Invalid row %d in Minimatrix::setBitmap\n", row);
- }
- return self;
- }
-
-
- /*
- * The size of the image (TIFF or PS) we are using to build the block.
- * Currently 16x16 is the image size.
- */
- - setElementSize:(const NXSize *)aSize
- {
- elementSize = *aSize;
- return self;
- }
-
- /*
- * Set the number of pixels away from the border the pieces will be.
- */
- - setInset:(const NXSize *)aSize
- {
- inset = *aSize;
- insetBounds = bounds;
- NXInsetRect(&insetBounds, inset.width, inset.height);
- return self;
- }
-
- /*
- * Set the amount of space to leave between each cell.
- */
- - setIntercell:(const NXSize *)aSize
- {
- intercell = *aSize;
- return self;
- }
-
- - free
- {
- NX_FREE(iconMatrix);
- return [super free];
- }
-
- @end
-
-